#include "fcntl.h"
#include "ota.h"
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "device.h"
#include "resource.h"
#include "console.h"
#include "config.h"
#include "flash.h"


#define Start_address  0x80005000
typedef void (*pFunc)(void);
#define pfn_call_addr	pFunc
#define __microMIPS_instruction		1
#define __JUMP_TO(addr)	((pFunc)(((addr)&(~0x03))|__microMIPS_instruction))();

int running_loader(void)
{
    volatile uint8_t *p = (volatile uint8_t *) Start_address;
    part_t *ppart;
    if ((ppart = get_part_by_name("loader", NULL)) == NULL) {
        return -1;
    }
    if (verify_firmware2(ppart) <= 0) {
        return -2;
    }
    int len = 16 *  1024;
    int ret, offset = 0, size;
    uint8_t buf[256];
    while (len) {
      //  printf("len: %d\n", len);
        size = len > 256? 256 : len; 
        int i;

        //printf("size: %d\n", size);
        part_read(ppart,  offset, buf, size);
            //   for (i = 0; i < size; i ++) {
            //printf("%02x ", buf[i]);
        //}
        memcpy(p, buf, size);
        offset += size;
        len -= size;
        p += size;
        
    }
   // printf("\nRunning loader......\n");
    mdelay(100);
    __JUMP_TO(Start_address + 0x100);
    return 0;
}

int update_rxsys(void)
{
    int fd;
    
    fd = open("/appfs/rxsys.bin", O_RDWR);
    if (fd > 0) {
       // printf("Rxsys Update........");
       //lcd_clrscr(); 
       //lcd_disp_string(0, 25, "Rxsys Update........");
        if (running_loader() < 0) {
          //  printf("failed!\n"); 
           // lcd_disp_string(25, 40, "Rxsys failed!");
        }
    }
}

int package_update(void)
{
   // ota_update();
    update_rxsys();
    update_other_file();
}

void update_other_file(void)
{
    mod_update_t up;
    int fd, ret;

    fd = open("/appfs/app0.bin", O_RDWR);
    if (fd > 0) {
       // lcd_clrscr(); 
       // lcd_disp_string(0, 25, "app0 Update........");
     //   printf("app0 update......");
        strcpy(up.file_name, "/appfs/app0.bin");
        strcpy(up.mod_name, "app0");
       // ret = update_mod(&up, 1);
        ret = update_mod(&up, 1);
        if (ret < 0) {
          //  lcd_disp_string(0, 25, "app0 Failed");            
        //    printf("Failed: %d!\n", ret);  
        }
    }
    
    fd = 0; 
    ret = 0;
    fd = open("/appfs/emvlib.bin", O_RDWR);
    if (fd > 0) {
       // lcd_clrscr(); 
       // lcd_disp_string(0, 25, "Emvlib Update........");
       // printf("Emvlib update .......\n");
        strcpy(up.file_name, "/appfs/emvlib.bin");
        strcpy(up.mod_name, "emvlib");
        ret = update_mod(&up, 1);
        if (ret < 0) {
          //  lcd_disp_string(0, 25, "emvlib Failed");            
           // printf("Failed error: %d!\n", ret);  
        }
    }

   
    fd = 0; 
    ret = 0;
    fd = open("/appfs/loader.bin", O_RDWR);
    if (fd > 0) {
        //printf("RxLoader update ........");
        strcpy(up.file_name, "/appfs/loader.bin");
        strcpy(up.mod_name, "loader");
        ret = update_mod(&up, 1);
        if (ret < 0) {
          //  printf("loader Failed \n");  
        }
    }
}

#if 0

#define OTA_MAGIC  0x4F544144

#include "fcntl.h"
int update_loader(packet_info_t *pp)
{
    if (pp) {
        return update_by_ota(pp);    
    }
    else {
        return update_mod_bin("/appfs/loader.bin", "loader");
    }
    return 0;
}

int ota_update(void)
{
    ota_param_t ota;
    int i, fd, flag = 0, ret;
    
    fd = open("/appfs/otasys.bin", O_RDWR);
    if (fd > 0) {
        printf("OTA Update........");
        ret = read(fd, &ota, sizeof(ota_param_t));
        if (ret < 0) {
            printf("OTA update failed!\n");
        }
        else {
             if (ota.magic == 0x4F544144) {
                printf("OTA Magic verify success !\n");
                for (i = 0; i < ota.nr; i ++) {
                    if (!strcmp("loader", ota.paket[i].name)) {
                        printf("OTA Loader update .......");
                        if (update_by_ota(ota.paket[i].name) == 0) {
                            printf("success\n");
                        }
                        else {
                            printf("failed\n");
                            flag = 1;
                        }
                    }
                }
                if (!flag) {
                    for (i = 0; i < ota.nr; i ++) {
                        if (!strcmp("rxsys", ota.paket[i].name)) {
                            //fd = open("/appfs/rxsys.bin", O_RDWR);
                           // printf("fs : %d\n", fd);
                            printf("OTA RxSys update .......");
                            if (running_loader() < 0) {
                                printf("failed!\n");
                            }
                        }
                    }
                }
            }
        }
        close(fd);
        unlink("/appfs/otasys.bin");
    }
}
#endif

